/*
 * TCSS 360 - Autumn 2011
 * Group2: ManuscriptPR
 *
 * ManuscriptCollection class
 * Author: Daniel Bryant
 */

package document;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import user.Conference;
import user.Role;
import user.User;
import user.UserCollection;

/**
 * collection of Manuscripts grouped by User.
 * @author Daniel Bryant	(author for all)
 * @author Tony Butterfield (Author for loadAllTestData(), 
 *                            Co-Author for javadoc, add, and get methods)
 * @version 12/2/2011
 */
public class ManuscriptCollection 
{
  //STATIC FIELDS ****************************************
  /** test file token delimiter. */
  private static final String COMMA = ",";  


  // INSTANCE FIELDS **************************************
  /** backing store for collection using <Title, Manuscript> ast the Key/Value pair. */
  private Map<String, Manuscript> my_manuscripts;

  /** reference to UserCollection.  */
  private UserCollection my_users;

  
  // CONSTRUCTORS *****************************************
  /** 
   * a constructor, builds a new arraylist of manuscripts.
   * @param the_users UserCollection reference to retrieve User and Conference objects
   */
  public ManuscriptCollection(final UserCollection the_users)
  {
    my_users = the_users;
    my_manuscripts = new HashMap<String, Manuscript>();
  }

  
  // MUTATORS *********************************************
  /**
   * adds a manuscript to the collection.
   * @param the_user User author of the manuscript
   * @param the_title String title of the manuscript (from GUI text)
   * @param the_conference conference to which the manuscript is being submitted
   * @param the_file String with filepath to original document file
   ********************************************************
   * @requires  the_title != null && the_title = String && 
   *            the_file != null && the_file = String &&
   *            the_user != null && the_user = User &&
   *            the_conference != null && the_conference = Conference
   * @ensures   the addition of a new Manuscript object into the collection 
   */  // <<NEEDS TO FAIL IF NO FILE FOUND>>>
  public void addManuscript(final User the_user, final String the_title, 
                            final Conference the_conference, final String the_file) 
  {
    if (the_title != null && the_file != null && the_user != null && the_conference != null)
    {
      my_manuscripts.put(the_title, new Manuscript(the_user, the_title, the_conference, 
                                                   the_file));
    }
    else
    {
      throw new  IllegalArgumentException();
    }
  }
  
  /**
   * adds a manuscript to the collection.
   * @author Tony Butterfield
   * @param the_manuscript Manuscript to add
   ********************************************************
   * @requires the_manuscript = Manuscript
   */
  public void addManuscript(final Manuscript the_manuscript)
  {
    my_manuscripts.put(the_manuscript.getTitle(), the_manuscript);
  }
  
  
  
  // ACCESSORS ********************************************
  /**
   * get a manuscript by reference to its title.
   * @param the_title String containing title of manuscript
   * @return Manuscript with that title or null if no match
   */
  public Manuscript getManuscriptByTitle(final String the_title)
  {
    return my_manuscripts.get(the_title);    
  }
  
  /**
   * gets a list of any manuscripts submitted by an author.
   * @param the_author User who submitted the manuscript
   * @return List<Manuscript> containing any manuscripts
   ********************************************************
   * @requires the_author = User
   * @ensures method returns a List<Manuscript> of manuscripts by that author
   */
  public List<Manuscript> getManuscriptsByAuthor(final User the_author) 
  {
    final List<Manuscript> manuscripts = new ArrayList<Manuscript>();
    
    final List<String> title_list = getAllManuscriptTitles();
    Collections.sort(title_list);
    
    for (String t : title_list)
    {
      final Manuscript manuscript = getManuscriptByTitle(t);
      if (the_author == manuscript.getUser())
      {
        manuscripts.add(manuscript);
      }
    }    
    return manuscripts;  
  }
  
  /**
   * returns a sorted list of all manuscript titles in the collection.
   * @return List<String> with titles
   ********************************************************
   * @ensures the method returns a sorted List<String> with any titles
   */
  public List<String> getAllManuscriptTitles() 
  {
    final List<String> title_list = new ArrayList<String>(my_manuscripts.keySet());
    Collections.sort(title_list);

    return title_list;
  }


  // METHODS **********************************************
  /**
   * get number of manuscripts in collection.
   * @return int number
   */
  public int size() 
  {
    return my_manuscripts.size();
  }

  /**
   * load all test data.
   * @throws IOException 
   */
  public void loadAllTestData() throws IOException
  {
    final String separator = ", ";
    
    final File test_file = new File("manuscript_test.txt");

    final BufferedReader reader = new BufferedReader(new FileReader(test_file));
    String line = null;

    // get each line format: FIRSTNAME,LASTNAME,TITLE,CONFERENCENAME,FILENAME,
    //     with FIRSTNAME,LASTNAME,CONFERENCENAME repeated for each review
    while ((line = reader.readLine()) != null)
    {
      final StringTokenizer token = new StringTokenizer(line, COMMA);
      
      // load author
      final String fname = token.nextToken();
      final String lname = token.nextToken();
      final String title = token.nextToken();     //NOTE: a comma in the title will break this
      final String conf_name = token.nextToken();
      final String filename = token.nextToken();
      
      User author = my_users.getUser(lname + separator + fname);

      if (author == null)                                   // if author doesn't exist already
      {
        author = new User(fname, lname);                    // create him
        my_users.addUser(author);                           // add him to the UserCollection
      }

      Conference conference = author.getConference(conf_name);

      if (conference == null)                           // if author is not in conference
      {                                                 // get a reference from someone who is
        final User member = my_users.getUser(my_users.getConferenceMembers(conf_name).get(0));
        conference = member.getConference(conf_name);
        author.addConferenceRole(conference, Role.AUTHOR);  // add him as an author
      }      

      final Manuscript manuscript = new Manuscript(author, title, conference, filename);

      while (token.hasMoreTokens())                         // get each review
      {
        final String rfname = token.nextToken();
        final String rlname = token.nextToken();

        User reviewer = my_users.getUser(rlname + separator + rfname);

        if (reviewer == null)                             // if reviewer doesn't already exist
        {
          reviewer = new User(fname, lname);              // create
          my_users.addUser(reviewer);                     // and add
        }

        manuscript.addReviewer(reviewer);
        
        final String rfilename = token.nextToken();

        manuscript.addReviewDoc(reviewer, new Review(reviewer, rfilename));

      }
      addManuscript(manuscript);
    }
  }  
}






